#include "sys.h" 

static volatile uint32_t counter;
static void SycTickHandler(void) {
  counter++;
}

/**
 * @brief 系统配置
 * 
 * 配置时钟和滴答定时器
 * 
 */
void SYS_Init(void)
{
    ROM_FPUEnable();//使能浮点单元。这个函数必须在执行任何硬件浮点运算之前被调用;如果不这样做，将导致NOCP使用错误。
	ROM_FPULazyStackingEnable();//浮点延迟堆栈,减少中断响应延迟 
    
    /*进行系统时钟的初始化，
    SYSCTL_USE_PLL | SYSCTL_OSC_MAIN这一段话表示让PLL作为系统时钟的时钟源。
    SYSCTL_XTAL_16MHZ表示主振荡器为16MHZ
    SYSCTL_SYSDIV_5进行再次分频的。因为PLL输出400MHZ频率，返回进行了一次2分频之后是200MHZ。
    因为TM4C123最大频率40为MHZ
    */
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |SYSCTL_OSC_MAIN);

    /*进行systick滴答定时器进行配置
      SysTickPeriodSet(SysCtlClockGet() / 1000000UL); 设置滴答定时器的装在值，SysCtlClockGet()获取系统时钟频率80M
    80M/1M=80，装载值为80，那么中断进入的频率为80M/80=1us，这样就进行了计时操作
      SysTickIntRegister这个用于注册滴答定时器中断函数，当滴答定时器溢出时候，进入滴答定时器的中断函数
    */
	
    SysTickPeriodSet(SysCtlClockGet() / 1000000UL); //
    SysTickIntRegister(SycTickHandler);
    SysTickIntEnable();				//使能systick中断
    SysTickEnable();	           //使能systick计数器

}
/**
 * @brief 
 * 
 * @return 返回当计时多少毫秒
 */
uint32_t millis(void) {
	return counter / 1000UL;
}
/**
 * @brief 
 * 
 * @return 返回当前计时多少微秒
 */
uint32_t micros(void) {
	return counter;
}

/**
 * @brief 延时函数 单位us
 * 
 * @param us微秒
 */
void delayMicroseconds(uint32_t us) {
	uint32_t start = micros();
	while ((int32_t)(micros() - start) < us) {
	// Do nothing
	};
}
/**
 * @brief 延时函数 单位ms
 * 
 * @param ms毫秒
 */
void delay(uint32_t ms) {
	delayMicroseconds(ms * 1000UL);
}

void Delay_Ms(uint32_t x)
{
	delay(x);
}

void delay_ms(uint32_t x)
{
	Delay_Ms(x);
}

void delay_us(uint32_t x)
{
	delayMicroseconds(x);
}

void Delay_Us(uint32_t x) 
{
	delayMicroseconds(x);
}


/**
 * @brief Get the Time Period object
 * 获取一个函数上一次进来和下一次进来所用的时间
 * @param Time_Lab 
 */
void getTime_Period(getTime *Time_Lab)
{
	Time_Lab->Last_Time=Time_Lab->Now_Time;
	Time_Lab->Now_Time=micros()/1000.0f;
	Time_Lab->Time_Delta=(Time_Lab->Now_Time-Time_Lab->Last_Time);
	Time_Lab->Time_Delta_INT=(uint16_t)(Time_Lab->Time_Delta);
}

